#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h> 
#include <stdlib.h>       
#include <string.h>
#include <pthread.h>
//#include <sys/sem.h>
#include <errno.h>
#include <sys/ipc.h>
//#include <sys/msg.h>
#include <sys/timeb.h>
#include <sys/socket.h>
//#include <sys/socketvar.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <semaphore.h>
#include <string.h>
#include <termios.h>
#include <linux/input.h>
#include <semaphore.h>
#include <linux/shm.h>
#include <asm/unistd.h>
#include <sys/poll.h>

#include "common.h"

//#define _AUDIOMIX_EXT_
//#include "audioMix.h"   // [UDI_Chenqz]

struct recvAudioData
{
		unsigned char buf[1024];	
		struct recvAudioData *pNext;
};

static int audioPlayModuleInit = 0;
static pthread_mutex_t Lock;
static struct recvAudioData *recvAudioDataUse = NULL;
static struct recvAudioData *recvAudioDataEmpty = NULL;

static struct recvAudioData *CreateChainFrame(int length);
static void InsertHeadFrame(struct recvAudioData **dst,struct recvAudioData *src);
static void InsertTailFrame(struct recvAudioData **dst,struct recvAudioData *src);
static struct recvAudioData *GetHeadChainFrame(struct recvAudioData **dst);
static struct recvAudioData *GetTailChainFrame(struct recvAudioData **dst);


void audioPlay(struct recvData *recvData)
{
		struct recvAudioData *recvAudioDataTmp = NULL;
		
		if( audioPlayModuleInit == 0 )
		{
				pthread_mutex_init (&(Lock),0);
				if( ( recvAudioDataEmpty = CreateChainFrame(10) ) == NULL )
				{
						//LOGD("CreateChainFram error[%s:%d]",__FILE__,__LINE__);	
				}	
				audioPlayModuleInit = 1;					
		}
		
		
		if( recvData->buf[0] != 0xA1 ) return;
		if( recvData->count != 15 + 1024 ) return;	
		//printf("[%d]--%s(%d)\n",recvData->count,__FILE__,__LINE__);
		
		pthread_mutex_lock(&(Lock));	
		if( ( recvAudioDataTmp = GetHeadChainFrame(&recvAudioDataEmpty) ) == NULL )
					recvAudioDataTmp = GetHeadChainFrame(&recvAudioDataUse);
		pthread_mutex_unlock(&(Lock));	
		
		if( recvAudioDataTmp == NULL ) return;
			
		memcpy(recvAudioDataTmp->buf,recvData->buf+15,1024);
	
		pthread_mutex_lock(&(Lock));	
		InsertTailFrame(&recvAudioDataUse,recvAudioDataTmp);
		pthread_mutex_unlock(&(Lock));			
}

static struct recvAudioData *CreateChainFrame(int length)
{
		int i;
		struct recvAudioData *back = NULL;
		struct recvAudioData *temp = NULL;
		
		for( i = 0; i < length; i++ )
		{
				if( ( temp = (struct recvAudioData *)malloc(sizeof(struct recvAudioData)) ) == NULL )	
				{
						return NULL;	
				}		
				
				temp->pNext = back;
				back = temp;
		}
		
		return temp;
}

static void InsertHeadFrame(struct recvAudioData **dst,struct recvAudioData *src)
{
		struct recvAudioData *temp = src;
		
		if( temp == NULL ) return;
		
		while(temp->pNext!=NULL) temp = temp->pNext;
		
		temp->pNext = *dst;
		*dst = src;
}


static void InsertTailFrame(struct recvAudioData **dst,struct recvAudioData *src)
{
		struct recvAudioData *temp = *dst;
		
		if( temp == NULL )
		{
				*dst = src;
		}
		else
		{
				while(temp->pNext!=NULL) temp = temp->pNext;		
				temp->pNext = src;
		}
}

static struct recvAudioData *GetHeadChainFrame(struct recvAudioData **dst)
{
		struct recvAudioData *temp = *dst;
	
		if( (*dst) != NULL )
		{
				(*dst) = (*dst)->pNext;	
				temp->pNext = NULL;	
		}	
		
		return temp;
}

static struct recvAudioData *GetTailChainFrame(struct recvAudioData **dst)
{
		struct recvAudioData *temp = *dst;
		struct recvAudioData *back = NULL;
		
		if( temp == NULL )
		{
				return NULL;
		}
		else
		{
				if( temp->pNext == NULL )
				{
						*dst = NULL;
						return 	temp;	
				}					
					
				while(temp->pNext!=NULL) 
				{
						back = temp;
						temp = temp->pNext;	
				}	
				
				back->pNext = NULL;
				return temp;
		}
}

int GetAudioOneFrame(unsigned char*pData)
{
		struct recvAudioData *recvAudioDataTemp;
		
		if( audioPlayModuleInit == 0 ) return -1;	
		
		pthread_mutex_lock(&(Lock));	
		
		recvAudioDataTemp = GetHeadChainFrame(&recvAudioDataUse);
		
		if( recvAudioDataTemp != NULL )
		{		
				memcpy(pData,recvAudioDataTemp->buf,1024);
				
				InsertHeadFrame(&recvAudioDataEmpty,recvAudioDataTemp);
				
				pthread_mutex_unlock(&(Lock));	
				 
				return 0;				
		}  
				
		pthread_mutex_unlock(&(Lock));
		
		return -1;		
}	




